package com.hopu.v1.service.admin.classes.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hopu.v1.exception.BusinessException;
import com.hopu.v1.exception.NoLoginException;
import com.hopu.v1.mapper.admin.classes.StudentMapper;
import com.hopu.v1.mapper.admin.classes.StudentVoucherMapper;
import com.hopu.v1.pojo.classes.Student;
import com.hopu.v1.pojo.classes.StudentVoucher;
import com.hopu.v1.pojo.common.R;
import com.hopu.v1.service.admin.classes.StudentService;
import com.hopu.v1.service.admin.classes.StudentVoucherService;
import com.hopu.v1.utils.JwtUtils;
import com.hopu.v1.utils.SendMessage;
import com.hopu.v1.vo.EmploymentInfoVo;
import com.hopu.v1.vo.StudentClassVo;
import com.hopu.v1.vo.WxLogin;
import jakarta.servlet.http.HttpSession;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.time.LocalDate;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
* @author admin
* @description 针对表【t_student(学生表)】的数据库操作Service实现
* @createDate 2024-09-26 15:30:32
*/
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student>
    implements StudentService{
    private final RedisTemplate<String, String> redisTemplate;

    @Autowired
    private StudentVoucherService studentVoucherService;
    //应用id
    private String appid = "wxd99431bbff8305a0";
    //应用密钥
    private String secret = "60f78681d063590a469f1b297feff3c4";
    //微信回调地址
    private String redirect_uri = "http://www.pinzhi365.com/wxlogin";
    //微信登录地址
    private String wxLoginUrl = "https://open.weixin.qq.com/connect/qrconnect?appid="+appid+"&redirect_uri="+redirect_uri+"&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect";
    //获取access_token地址
    private String getAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";
    //获取微信用户信息地址
    private String getWxUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo";


    /**
     * 验证码有效期
     */
    @Value("${verification.code.expiration:300000}")
    private long expiration;

    public StudentServiceImpl(RedisTemplate<String, String> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private StudentVoucherMapper studentVoucherMapper;

    /**
     * 分页条件查询学生
     * @param page
     * @param student
     * @return
     */
    @Override
    public Page<StudentClassVo> selectAll(Page<Student> page, Student student) {
        if (Objects.equals(student.getStudentId(), "")){
            student.setStudentId(null);
        }
        if (Objects.equals(student.getName(), "")){
            student.setName(null);
        }
        if (Objects.equals(student.getClassId(), "")){
            student.setClassId(null);
        }
        return studentMapper.selectStudentClassByClassId(page,student);
    }

    /**
     * 修改停启用状态
     * @param id
     * @return
     */
    @Override
    public R statusUpdate(Integer id) {
        Student student = new Student();
        student.setId(id);
        if (getById(id).getStatus() == 1) {
            student.setStatus(0);
        }else {
            student.setStatus(1);
        }
        return R.ok("修改状态成功！", studentMapper.updateById(student));
    }

    @Override
    public Student getLastStudent() {
        return studentMapper.selectLastStudent();
    }

    /**
     *添加学生
     * @param student
     * @return
     */
    @Override
    public R addStudent(Student student) {
        synchronized (this) {
            String newStudentId = "";
            Student lastStudent = getLastStudent();
            int year = LocalDate.now().getYear();
            if (lastStudent == null) {
                newStudentId = year+"00001";
                student.setStudentId(newStudentId);
            }else {
                Long i = Long.parseLong(lastStudent.getStudentId()) + 1;
                String lastStudentId = String.valueOf(i).substring(4,9);
                newStudentId = year+lastStudentId;
                student.setStudentId(newStudentId);
            }
            if (checkStudentId(student,"add")){
                return R.err("该学号已存在！");
            }
            student.setStatusGraduation(1);
            boolean save = save(student);
            if (save){
                StudentVoucher studentVoucher = new StudentVoucher();
                studentVoucher.setStudentId(student.getStudentId());
                studentVoucher.setVoucherType("password");
                studentVoucher.setVoucher("123456");
                studentVoucherService.save(studentVoucher);
            }
            return R.ok("添加成功！",newStudentId);
        }
    }

    /**
     * 修改学生
     * @param student
     * @return
     */
    @Override
    public R updateStudent(Student student) {
        if (checkStudentId(student,"update")){
            return R.err("该学号已存在！");
        }
        return R.ok("修改成功！",updateById(student));
    }

    /**
     * 学号验重
     * @param student
     * @return
     */
    @Override
    public boolean checkStudentId(Student student , String string) {
        List<Student> students = studentMapper.selectList(new LambdaQueryWrapper<Student>().eq(Student::getStudentId, student.getStudentId()));
        if (students == null  || students.isEmpty()){
            return false;
        }
        if (!string.equals("add")) {
            for (Student s : students) {
                if (Objects.equals(s.getStudentId(), student.getStudentId())) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 登录
     * @param studentId
     * @param voucher
     * @return
     */
    @Override
    public R login(String studentId,String voucher) {
        StudentVoucher studentVoucher = studentVoucherMapper.selectOne(
                new LambdaQueryWrapper<StudentVoucher>()
                        .eq(StudentVoucher::getStudentId, studentId)
                        .eq(StudentVoucher::getVoucherType, "password")
        );

        if (studentVoucher == null) {
            throw new NoLoginException("学号错误！");
        }

        if (!studentVoucher.getVoucher().equals(voucher)) {
            throw new NoLoginException("密码错误！");
        }

        return R.ok("登陆成功", JwtUtils.createToken(studentId));
    }

    //检验手机号是否被注册

    @Override
    public boolean checkPhone(String telephone) {
        // 查询学生是否存在
        Student selectOne = studentMapper.selectOne(new LambdaQueryWrapper<Student>().eq(Student::getTelephone, telephone));
        if (selectOne == null) {
            return false;
        }else {
            return true;
        }
    }



    @Override
    public String sendCode(String telephone) {
        // 检查 telephone 是否为 null 或空字符串
        if (telephone == null || telephone.trim().isEmpty()) {
            throw new IllegalArgumentException("电话号码不能为空");
        }

        // 检查手机号码格式是否正确
        if (!telephone.matches("^\\d{11}$")) {
            throw new NoLoginException("手机号格式错误，请重新输入");
        }

        // 查询学生是否存在
        Student selectOne = studentMapper.selectOne(new LambdaQueryWrapper<Student>().eq(Student::getTelephone, telephone));
        if (selectOne == null) {
            throw new NoLoginException("该学生未注册或未绑定手机号");
        }

        // 发送验证码
        String code = SendMessage.send(telephone);
        redisTemplate.opsForValue().set(telephone, code, expiration, TimeUnit.MILLISECONDS);
        System.out.println(telephone + "的验证码是：" + code);
        return code;
    }

    @Override
    public R login2(String telephone, String code) {
        // 检查 telephone 是否为 null 或空字符串
        if (telephone == null || telephone.trim().isEmpty()) {
            throw new IllegalArgumentException("电话号码不能为空");
        }

        // 检查手机号码格式是否正确
        if (!telephone.matches("^\\d{11}$")) {
            throw new NoLoginException("手机号格式错误，请重新输入");
        }

        // 查询学生是否存在
        Student selectOne = studentMapper.selectOne(new LambdaQueryWrapper<Student>().eq(Student::getTelephone, telephone));
        if (selectOne == null) {
            throw new NoLoginException("该学生未注册，请重新输入");
        }

        // 验证验证码
        String sendCode = redisTemplate.opsForValue().get(telephone);
        try {
            if (sendCode != null && sendCode.equals(code)) {
                return R.ok("登陆成功", JwtUtils.createToken(String.valueOf(selectOne.getStudentId())));
            }
            throw new NoLoginException("验证码错误");
        } catch (Exception e) {
            e.printStackTrace();
            throw new NoLoginException("验证码错误");
        }
    }

    @Override
    public R login3(String code, HttpSession session) throws IOException {
        String accessTokenUrl = getAccessTokenUrl + "?appid=" + appid + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code";
        Document document = Jsoup.connect(accessTokenUrl).ignoreContentType(true).get();
        String body = document.getElementsByTag("body").get(0).text();
        JSONObject jsonObject = JSONObject.parseObject(body);
        String openId = jsonObject.getString("openid");

        StudentVoucher studentVoucher = studentVoucherMapper.selectOne(
                new LambdaQueryWrapper<StudentVoucher>()
                        .eq(StudentVoucher::getVoucherType, "wx")
                        .eq(StudentVoucher::getVoucher, openId)
        );

        if (studentVoucher == null) {
//          String result = studentVoucherService.bindStudentId(null,null,openId);
////            if (result.equals("该学生绑定成功")) {
////                studentVoucher.setVoucher(openId);
////            } else {
////                return R.err(result);
////            }
            return R.err("请绑定微信",openId);
        }

        WxLogin wxLogin = new WxLogin();
        wxLogin.setStudentId(studentVoucher.getStudentId());
        wxLogin.setToken(JwtUtils.createToken(studentVoucher.getStudentId()));
        return R.ok("登陆成功", wxLogin);
    }

    @Override
    public Student studentInfo(String studentId) {
        //查询个人
        Student student = studentMapper.selectOne(new LambdaQueryWrapper<Student>().eq(Student::getStudentId,studentId ));
        return student;
    }

    @Override
    public Student studentInfoByphone(String telephone) {
        Student student = studentMapper.selectOne(new LambdaQueryWrapper<Student>().eq(Student::getTelephone,telephone));
        return student;
    }

    @Override
    public Student studentInfoByOpenId(String openId) {
        //根据openId获取学生信息
        //Student student = studentMapper.selectOne(new LambdaQueryWrapper<Student>().eq());
        return null;
    }

    /**
     * 查询班级的所有考勤
     * @param classId
     * @return
     */
    @Override
    public List<Student> selectAttendance(Integer classId) {
        return studentMapper.selectAttendance(classId);
    }
	
	@Transactional
	@Override
	public void updateStudent(EmploymentInfoVo student) {
		Student studentInfo = new Student();
		studentInfo.setId(student.getId());
		studentInfo.setNickname(student.getNickname());
		studentInfo.setName(student.getName());
		studentInfo.setGender(student.getGender());
		studentInfo.setTelephone(student.getTelephone());
		studentInfo.setIdCard(student.getIdCard());
		studentInfo.setBirthday(student.getBirthday());
		studentInfo.setNativePlace(student.getNativePlace());
		studentInfo.setAddress(student.getAddress());
		studentInfo.setPoliticalOutlook(student.getPoliticalOutlook());
		
		StudentVoucher studentVoucher = new StudentVoucher();
		studentVoucher.setStudentId(student.getStudentId());
		studentVoucher.setVoucher(student.getPassword());
		
		baseMapper.updateById(studentInfo);
		
		studentVoucherMapper.update(studentVoucher);
	}
	
	@Override
	public void bindingWeChat(String studentId, String code, String state, HttpSession session) throws IOException {
		String accessTokenUrl = getAccessTokenUrl + "?appid=" + appid + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code";
		Document document = Jsoup.connect(accessTokenUrl).ignoreContentType(true).get();
		String body = document.getElementsByTag("body").get(0).text();
		JSONObject jsonObject = JSONObject.parseObject(body);
		String openId = jsonObject.getString("openid");
		System.out.println("openId = " + openId);
		StudentVoucher studentVoucher = studentVoucherMapper.selectOne(new LambdaQueryWrapper<StudentVoucher>().eq(StudentVoucher::getStudentId, studentId).eq(StudentVoucher::getVoucherType, "wx"));
		
		//如果凭证表有数据
		if (studentVoucher != null) {
			throw new BusinessException("当前账号已绑定微信");
		}
		StudentVoucher voucher = new StudentVoucher();
		voucher.setStudentId(studentId);
		voucher.setVoucherType("wx");
		voucher.setVoucher(openId);
		studentVoucherMapper.insert(voucher);
	}

    /**
     * 绑定手机
     * @param phoneNum
     * @return
     */
    @Override
    public R bindingPhone(String studentId,String password,String phoneNum) {
        StudentVoucher studentVoucher = new StudentVoucher();
        studentVoucher.setStudentId(studentId);
        studentVoucher.setVoucherType("password");
        studentVoucher.setVoucher(password);
        if (checkPW(studentVoucher)){
            Student student = new Student();
            student.setStudentId(studentId);
            student.setTelephone(phoneNum);
            return R.ok("绑定成功！",studentMapper.updatePhoneNum(student));
        }else {
            return R.err("账号或密码错误！");
        }

    }

    @Override
    public String newSendCode(String telephone) {
            // 检查 telephone 是否为 null 或空字符串
            if (telephone == null || telephone.trim().isEmpty()) {
                throw new IllegalArgumentException("电话号码不能为空");
            }

            // 检查手机号码格式是否正确
            if (!telephone.matches("^\\d{11}$")) {
                throw new NoLoginException("手机号格式错误，请重新输入");
            }

            // 发送验证码
            String code = SendMessage.send(telephone);
            redisTemplate.opsForValue().set(telephone, code, expiration, TimeUnit.MILLISECONDS);
            System.out.println(telephone + "的验证码是：" + code);
            return code;
    }

    @Override
    public R checkCode(String telephone, String code) {
        // 验证验证码
        String sendCode = redisTemplate.opsForValue().get(telephone);
        try {
            if (sendCode != null && sendCode.equals(code)) {
                return R.ok();
            }
            throw new NoLoginException("验证码错误");
        } catch (Exception e) {
            e.printStackTrace();
            throw new NoLoginException("验证码错误");
        }
    }

    /**
     * 查验学号密码
     * @param studentVoucher
     * @return
     */
    boolean checkPW(StudentVoucher studentVoucher){
        LambdaQueryWrapper<StudentVoucher> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StudentVoucher::getStudentId,studentVoucher.getStudentId());
        wrapper.eq(StudentVoucher::getVoucherType,studentVoucher.getVoucherType());
        StudentVoucher one = studentVoucherMapper.selectOne(wrapper);
        if (one != null){
            return one.getVoucher().equals(studentVoucher.getVoucher());
        }else {
            return false;
        }
    }

    @Override
	public String getStudentPassword(String studentId) {
		QueryWrapper<StudentVoucher> queryWrapper = new QueryWrapper<StudentVoucher>().eq("student_id", studentId).eq("voucher_type","password");
		StudentVoucher studentVoucher = studentVoucherMapper.selectOne(queryWrapper);
		return studentVoucher.getVoucher();
	}
}




